/**
 * 格式化折线类和柱形类数据
 * @des {
 *   仅格式化组件所需要的X轴，Y轴和series数据，不处理属性的值
 * }
 */

import { $each } from '../index';
import { isEmptyArr, isNullOrEmpty } from '../is';
import { handleConditionExtend } from '../conditionFormat/useConditionFormat.js';
import { handleChangeGroup }  from '../changeGroup.js';

/**
 * 格式化X轴
 * @param {object} datasets
 */
export function processXAis(datasets) {
  const { dimensions, source, fieldNameChainMap, conditionData } = datasets;
  const xData = [];
  const xMap = {};
  const conditionXMap = {};
  const { xAxis, legend } = dimensions;
  // 判断是否是多维度
  let xAxisArr = [];
  if (xAxis && xAxis.includes('&')) {
    xAxisArr = xAxis.split('&');
  } else {
    xAxisArr = [xAxis];
  }
  source.forEach((item) => {
    let XAXIS = '';
    // 联动使用
    const values = [];
    // 如果存在多维度，需要拼接起来显示
    if (xAxisArr.length) {
      xAxisArr.forEach((xAxisItem, index) => {
        const itemValue =  item[xAxisItem] || '';
        if (index !== 0) {
          XAXIS += itemValue ? `-${itemValue}` : '';
        } else {
          XAXIS = itemValue;
        }
        values.push(itemValue);
          // 如果颜色维度存在,维度数据需要去重
        if(legend) {
          // 根据原始字段名称收集数据 维度数据存在相同的数据需要去重
          if (fieldNameChainMap?.xAxis[xAxisItem] && !conditionXMap[item[xAxisItem]]) {
            conditionData[fieldNameChainMap?.xAxis[xAxisItem]].push({ value: itemValue });
            conditionXMap[item[xAxisItem]] = true;
          }
        } else {
          if (fieldNameChainMap?.xAxis[xAxisItem]) {
            conditionData[fieldNameChainMap?.xAxis[xAxisItem]].push({ value: itemValue });
          }
        }
      });
    }
    // 去重
    if (!xMap[XAXIS]) {
      xData.push({
        value: XAXIS|| '',
        values,

      });
      xMap[XAXIS] = true;
    }
  });
  return xData;
}

/**
 * 格式化series
 * @param {object} datasets
 * @param {Array} xData x轴数据
 * @param {object} option 多余参数
 */
export function processSeriesData(datasets, option) {
  const seriesData = [];
  const { source, fieldNameChainMap, conditionData, conditionOptions,type, sourceMap = {} } = datasets;
  // 注意，dataFormatType主要为了区分数据格式，比如双向柱状图，度量上下都配置了数据格式的话，无法区分出来
  const { xData, yAxis, legend: legendKey, xAxis, componentType, dataFormatType = 'yAxis', yAxisCondition, realDataObj, dataType, realYAxis, isForecastOrRealData, open, barStack, dataSourceType, measure, conditionType, forecastDays} = option;
  let yAxisArr = [];
  let xAxisArr = [];
  let yAxisConditionArr = [];//用来单独存储条件项名称
  const yAxisNameMap = ['yAxisBar', 'yAxis', 'yAxisLine']; // 所有度量名称
  // 判断是否是多维度
  if (xAxis && xAxis.includes('&')) {
    xAxisArr = xAxis.split('&');
  } else {
    xAxisArr = [xAxis];
  }
  // 判断是否是多度量
  if (yAxis && yAxis.includes('&')) {
    yAxisArr = yAxis.split('&');
  } else {
    yAxisArr = [yAxis];
  }
  if (!yAxis) {
    return [];
  }
  // 条件项存在多度量
  if (yAxisCondition && yAxisCondition.includes('&')) {
    yAxisConditionArr = yAxisCondition.split('&');
  } else {
    yAxisConditionArr = [yAxisCondition];
  }
  // 如果不存在颜色维度
  if (!legendKey) {
    yAxisArr.forEach((yItem, index) => {
      const yData = [];
      source.forEach((item, sourceIndex) => {
        let itemData = null;
        // 如果存在，说明是预测图
        if (realDataObj && realDataObj.length) {
          const info = realDataObj[index];
          itemData = {
            value: info?.index === '' || info?.index > sourceIndex ? item[info.key] : item[yItem],
          };
          //测试预测天数,按预测天数显示数据，否则显示全部数据
          if(forecastDays) {
            if( sourceIndex < (info.index + forecastDays)) {
              yData.push(itemData);
            }
          }else {
              yData.push(itemData);
          }
        } else {
          if (!isNullOrEmpty(item[yItem])) {
            itemData = {
              value: handleMeasure(measure ,item[yItem]),
              componentType, // 用来区别柱折图是柱状度量还是折线度量
            };
          }

          if (dataType === 'forecast' && item[yItem] == null) {
            itemData = {
              value: '-',
              componentType, // 用来区别柱折图是柱状度量还是折线度量
            };
          }
          yData.push(itemData);
        }
      });
      // 如果是预测图调用多添加一个字段
      let temp = {
        isForecastOrRealData,
        dataFormatType,
        componentType,
        name: yItem,
        data: yData,
      };
      // 开启双Y轴
      if (open) {
        //静态数据，柱子左轴，折线右轴
        if(type ==='STATIC') {
          temp.yAxisIndex = componentType === 'bar' ? 0 : 1;
        } else {
              Object.keys(sourceMap).forEach(key=>{
                const {name, yAxisIndex} = sourceMap[key] || {};
                if(name === temp.name) {
                  temp.yAxisIndex = yAxisIndex === 'left' ? 0  : 1;
                }
              })
        }
      }
      // 条形图堆叠
      if (barStack) {
        temp.stack = barStack;
      }
      seriesData.push(temp)

      // 根据原始字段名称收集数据
      yAxisNameMap.forEach((item) => {
        if (fieldNameChainMap[item] && fieldNameChainMap[item][yItem]) {
          conditionData[fieldNameChainMap[item][yItem]].push(...yData);
        }
      });
    });
    // 条件项存在
    if(!isEmptyArr(yAxisConditionArr)) {
      yAxisConditionArr.forEach((yItem) => {
        const yConditionData = [];
        source.forEach((item) => {
          if (item[yItem]) {
            yConditionData.push({
              value: handleMeasure(conditionType ,item[yItem]),
            });
          }
        });
        // 根据原始字段名称收集数据
        if(fieldNameChainMap['yAxisCondition'] && fieldNameChainMap['yAxisCondition'][yItem]) {
          conditionData[fieldNameChainMap['yAxisCondition'][yItem]].push(...yConditionData);
        }
      });
    }
    // 条件格式处理
    const options = {
      conditionData,
      isExistLegend: false, // 是否存在颜色维度
      seriesData,
      legendFieldName: null,
      fieldNameChainMap,
    };
    handleConditionExtend(options, conditionOptions);
    return seriesData;
  }
  const sourceData = type ==='STATIC' && isForecastOrRealData ? source.filter(item=> item.type === componentType): source;
  const legendMap = sourceData.reduce((acc, current, sourceIndex) => {
    let name = '';
    xAxisArr.forEach((xItem) => {
      name += `-${current[xItem]}`;
    });
    const value  = handleMeasure(measure ,current[yAxisArr[0]]);
    const conditionValue =  handleMeasure(conditionType ,current[yAxisConditionArr[0]]);
    if (acc[current[legendKey]]) {
      acc[current[legendKey]].push({
        name: name.substring(1),
        value,
        // 预测实线值
        realValue: current[realYAxis],
        conditionValue,// 条件项值
        type: current.type || '',
      });
    } else {
      acc[current[legendKey]] = [
        {
          name: name.substring(1),
          value,
          // 预测实线值
          realValue: current[realYAxis],
          conditionValue,// 条件项值
          type: current.type || '',
        },
      ];
    }
    return acc;
  }, {});
  let legendIndex = 0;
  $each(legendMap, (list, name) => {
    let result = {};
    const data = [];
    const yConditionData = []; // 颜色维度存在时的条件项数据
    const info = realDataObj && realDataObj.find(item => item.key === name);
    xData.forEach((xItem, index) => {
      // 遍历list数组中每一项的name值与xData数组中的每一项的value值进行查找
      result = list.find((item) => item.name === xItem.value) || { type: list[0].type };
      let value;
      if (info && info.index != null) {
        if (info.index === '') {
          value = result.realValue
        } else if (info.index >= index) {
          value = list[info.index].value
        } else {
          value = result.realValue
        }
      } else {
        value = isNullOrEmpty(result?.value) ? 0 : isForecastOrRealData ?  result.value || '-' : result.value;
      }
      // 如果存在，说明是预测图
      //测试预测天数,按预测天数显示数据，否则显示全部数据
      if(forecastDays && isForecastOrRealData === 'forecast') {
        if(index < (realDataObj[legendIndex].index + forecastDays)){
          data.push({
            value,
          });
        }
      } else{
        data.push({
          value,
        });
      }
      yConditionData.push({
        value: result?.conditionValue || 0,
      })
    });
    legendIndex++;
    if (name) {
      // 找对应第几项
      const nameIndex = componentType==="line" && isForecastOrRealData ? 1 :  Object.keys(legendMap).indexOf(name);
      const legendSerise = {
        isForecastOrRealData,
        componentType: result.type || componentType,
        dataFormatType,
        name: type ==='STATIC' && isForecastOrRealData === 'forecast' ? `预测${name}`: name ,
        data,
        // 开启双Y轴
        yAxisIndex: yAxisIndexFormat(open, componentType || result.type, nameIndex)
      }
      if(dataSourceType === 'STATIC' && result.type ==='line') {
        legendSerise.dataFormatType =  'yAxisLine';
      }
      seriesData.push(legendSerise)
      // 根据原始字段名称收集数据
      if (fieldNameChainMap.legend && fieldNameChainMap.legend[legendKey]) {
        conditionData[fieldNameChainMap.legend[legendKey]].push({ value: name });
      }
      yAxisNameMap.forEach((item) => {
        if (fieldNameChainMap[item] && fieldNameChainMap[item][yAxis]) {
          conditionData[fieldNameChainMap[item][yAxis]].push(...data);
        }
      });
      // 条件项根据原始字段名收集数据
      if(fieldNameChainMap['yAxisCondition'] && fieldNameChainMap['yAxisCondition'][yAxisCondition]) {
        conditionData[fieldNameChainMap['yAxisCondition'][yAxisCondition]].push(...yConditionData);
      }
    }
  });
  // 条件格式处理
  const options = {
    conditionData,
    isExistLegend: true, // 是否存在颜色维度
    seriesData,
    legendFieldName: fieldNameChainMap['legend'] && fieldNameChainMap['legend'][legendKey],
    fieldNameChainMap,
  };
  handleConditionExtend(options, conditionOptions);
  return seriesData;
}

//处理双向柱状图度量上(正数)，度量下数据(负数)
function handleMeasure(type, value) {
  let itemValue = null;
  switch(type) {
    case 'up':
    itemValue= value < 0 ? -value : value;
    break;
    case 'down':
    itemValue= value > 0 ? -value : value;
    break;
    default:
    itemValue= value;
  }
  return itemValue;
}

// 格式双Y轴，并返回yAxisIndex值
function yAxisIndexFormat(open, componentType, index) {
  if (!open) {
    return undefined;
  }
  const isComponentType = open && componentType;
  const isDoubleLine = isComponentType && componentType === 'line';
  const isDoubleBar = isComponentType && componentType === 'bar';

  // 偶数为柱状
  if (isDoubleBar && index % 2 === 0) {
    return 0;
  }

  // 奇数为折线
  if (isDoubleLine && index % 2 !== 0) {
    return 1;
  }
}

// 双Y轴format
export function barAndLineFormatDoubleYFormat(datasets) {
  return barAndLineFormat(datasets, 'doubleAxis');
}

/**
 * 柱折图格式化数据
 */
export function barAndLineFormat(datasets, isDoubleYAxis) {
  const { dimensions, type } = datasets;
  const { yAxis, legend, xAxis, yAxisLine } = dimensions;
  const xAxisData = processXAis(datasets);
  if (type === 'STATIC') {
    const seriesData = processSeriesData(datasets, {
      xData: xAxisData,
      yAxis,
      legend,
      xAxis,
      dataSourceType: type,
      open: isDoubleYAxis && isDoubleYAxis === 'doubleAxis'
    });
    return {
      seriesData,
      xAxisData,
    };
  }
  const open = isDoubleYAxis && isDoubleYAxis === 'doubleAxis';
  const barSeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    yAxis,
    legend,
    xAxis,
    dataFormatType: 'yAxis',
    componentType: 'bar',
    open,
  });
  const lineSeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    yAxis: yAxisLine,
    legend,
    xAxis,
    dataFormatType: open ? 'yAxisLine' : 'yAxis',
    componentType: 'line',
    open,
  });
  return {
    seriesData: [
      ...barSeriesData,
      ...lineSeriesData,
    ],
    xAxisData,
  };
}

/**
 * 双向柱状图格式化
 */
export function barDoubleChartFormat(datasets, extra) {
  const { selectStackOptions } = extra;
  const { dimensions, type } = datasets;
  const { yAxis, legend, xAxis, yAxisBar, yAxisCondition } = dimensions;
  const xAxisData = processXAis(datasets);
  let seriesData = [];
  if (type === 'STATIC') {
    seriesData = processSeriesData(datasets, {
      xData: xAxisData,
      yAxis,
      legend,
      xAxis,
    });
  }else {
    //度量上
    const conditionType = yAxisCondition === yAxis ? 'up' : yAxisCondition ===yAxisBar ? 'down' : '';
    const seriesDataUp = processSeriesData(datasets, {
      xData: xAxisData,
      yAxis,
      legend,
      xAxis,
      yAxisCondition,
      conditionType,
      measure: 'up'
    });
    //度量下
    const seriesDataDown = processSeriesData(datasets, {
      xData: xAxisData,
      yAxis: yAxisBar,
      legend,
      xAxis,
      yAxisCondition,
      measure: 'down'
    });
    seriesData = [
      ...seriesDataUp,
      ...seriesDataDown,
    ];
  }
  seriesData= handleChangeGroup(seriesData, selectStackOptions) ;
  return {
    seriesData,
    xAxisData,
  };
}
/**
 * 基本柱状，折线图
 * @params datasets 数据
 * @params {object} option 多余参数
 */
export function baseBarOrLineFormat(datasets, options = {}) {
  const { yAxis, legend, xAxis, yAxisCondition } = datasets.dimensions;
  const { key } = options;
  const xAxisData = processXAis(datasets);
  let seriesData = [];
  const params = {
    datasets,
    xAxisData,
    yAxis,
    legend,
    xAxis,
    yAxisCondition
  }
  if (lineStrategy[key]) {
    seriesData = lineStrategy[key](params);
  } else {
    seriesData = baseDealBarOrLineSeries(params);
  }
  return {
    seriesData,
    xAxisData,
  };
}

// 折线和柱状类通用series
function baseDealBarOrLineSeries(options) {
  const { datasets, xAxisData, yAxis, legend, xAxis, yAxisCondition} = options;
  return processSeriesData(datasets, {
    xData: xAxisData,
    yAxis,
    legend,
    xAxis,
    yAxisCondition,
    dataFormatType: 'yAxis',
  });
}

// 特殊折线分组series
function specialLineSeries(options) {
  const { datasets, xAxisData, yAxis, xAxis, yAxisCondition} = options;
  const legend = datasets.type === 'STATIC' ? 'name' : undefined;
  return processSeriesData(datasets, {
    xData: xAxisData,
    yAxis,
    legend,
    xAxis,
    yAxisCondition,
    dataFormatType: 'yAxis',
  });
}

//*******************************************************
// 折线组件策略
const lineStrategy = {
  // 单折线
  chart_line_basic(options) {
    const seriesData = baseDealBarOrLineSeries(options);
    return seriesData.length ? [seriesData[0]] : seriesData;
  },
  // 堆叠，阶梯折线图
  special_line(options) {
    const seriesData = specialLineSeries(options);
    return seriesData;
  },
}


//轴坐标热力图
export function otherHeatmapFormat(datasets) {
  const { dimensions, type, source } = datasets;
  const { yAxis, xAxis } = dimensions;
  const dataList = [];
  const yData= [];
  let count = 0;
  const xData = [];
  if(type === 'STATIC' && !isEmptyArr(source)) {
   //首先存储yAxis.data,和xAxis.data
    source.forEach(item=>{
    !yData.includes(item[yAxis])&& yData.push(item[yAxis]);
    !xData.includes(item[xAxis])&& xData.push(item[xAxis]);
  })
  //根据yData和xData数据长度去循环存储数据
  for(let i = 0; i< yData.length; i++) {
    for(let j = 0; j< xData.length; j++) {
        const { value = 0, x, y } = source[count] || {};
        let itemValue = '';
        //如何当前数据x,y不等于循环的value为'-'
        if( x!=xData[j] || y!=yData[i] ) {
          itemValue = '-'
        } else {
          itemValue = value || '-'
          count ++;
        }
        dataList.push([j, i,  itemValue] );
  }
  }
}
  return {
    seriesData: [{data: dataList}],
    xAxisData: {data: xData},
    yAxisData: {data: yData},
  };
}
//基础水位图
export function waterFormat(datasets) {
  const { dimensions, type, source } = datasets;
  const { yAxis } = dimensions;
  const yAxisArr = yAxis.split('&')
  const data = [];
  let value = null;
  const item = source[0] || {};
  if(type === 'STATIC'){
    value = item.value;
  } else {
    value = item[yAxisArr[0]];
  };
  !isNullOrEmpty(value) && data.push({value: `${value * 100..toFixed(0)}%`})
   return {
     seriesData: [ {data: data} ]
   }
}
